/**
 * 
 */
package main.java.tutorial.springmvc.controller;

/**
 * @author l.pelosi
 *
 */

import java.util.Locale;

import javax.servlet.http.HttpSession;
import javax.validation.Valid;

import main.java.tutorial.springmvc.model.PersonForm;

import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseStatus;

@Controller
public class DemoController
{
	
    @RequestMapping(value="/back2home", method=RequestMethod.GET)     
    public String back2homeRequestMapping() 
    {
    	System.out.println("back2homeRequestMapping");
        return "home";
    }
    
    @RequestMapping(value="/request", method=RequestMethod.GET)     
    public String simpleRequestMapping() 
    {
    	System.out.println("simpleRequestMapping with GET");
        return "demo_index";
    }    
    
    @RequestMapping(value="/request", method=RequestMethod.POST)     
    public String simpleRequestMappingWithPOST() 
    {
    	System.out.println("simpleRequestMapping with POST");
        return "demo_index";
    }    
    
    @RequestMapping(value="/request/{pathvar}/{pathvar2}", method=RequestMethod.GET)     
    public String requestMappingWithPathVariable(@PathVariable("pathvar") int id1, @PathVariable("pathvar2") int id2) 
    {
    	System.out.println("Con @PathVariable 1= "+id1);
    	System.out.println("Con @PathVariable 2= "+id2);
    	
        return "demo_index";
    }
    
    //Questo @RequestMapping deve avere un "value" diverso dal primo altrimenti saranno indistinguibili e avremo un errore "Ambiguous mapping found"
    @RequestMapping(value="/requestWithParam", method=RequestMethod.GET)     
    public String requestMappingWithRequestParam(@RequestParam("reqPar") String id) 
    {
    	System.out.println("Con @RequestParam = "+id);
    	
        return "demo_index";
    }
    
    @RequestMapping(value="/requestWithAdvancedParams", method=RequestMethod.POST)     
    public String requestMappingWithAdvancedParams(@RequestHeader("user-agent") String userAgent, @RequestBody String body, HttpSession session, Locale locale, Model model) 
    {    	
    	System.out.println("Con @RequestHeader('user-agent') = "+userAgent);
    	System.out.println("Con @RequestBody = "+body);
    	System.out.println("Con HttpSession = "+session.toString());
    	System.out.println("Con Locale = "+locale);
    	System.out.println("Con Model = "+model.toString());
    	
        return "demo_index";
    }
    
    
    //Redirect 
    @RequestMapping(value="/simpleRedirect", method=RequestMethod.GET)     
    public String redirectRequestMapping(@RequestParam("reqPar") String par) 
    {
    	System.out.println("simple redirect");
        return "redirect:to_redirectedRequest";
    } 
    @RequestMapping(value="/to_redirectedRequest", method=RequestMethod.GET)     
    public String redirectedRequestMapping(@RequestParam(value="reqPar",required=false) String par) 
    {
    	System.out.println("redirect avvenuto correttamente");
    	System.out.println("parametro proveniente dalla request originale: "+par);
        return "demo_index";
    }    

    //Forward 
    @RequestMapping(value="/simpleForward", method=RequestMethod.GET)     
    public String forwardRequestMapping(@RequestParam("reqPar") String par) 
    {
    	System.out.println("simple forward");
        return "forward:to_forwardedRequest";
    } 
    @RequestMapping(value="/to_forwardedRequest", method=RequestMethod.GET)     
    public String forwardedRequestMapping(@RequestParam("reqPar") String par) 
    {
    	System.out.println("forward avvenuto correttamente");
    	System.out.println("parametro proveniente dalla request originale: "+par);
        return "demo_index";
    }
    
    //Forward with Model
    @RequestMapping(value="/simpleModelRequest", method=RequestMethod.GET)     
    public String simpleModelRequestMapping(Model model) 
    {
    	
    	System.out.println("modelRequestMapping");
    	System.out.println("Aggiungo attributi ad un Model e questo viene implicitamente passato alla JSP destinazione");
    	model.addAttribute("attr1", "prova1");
    	model.addAttribute("attr2", "prova2");
        return "demo_index";
    }
    
    //ViewResolver Custom
    @RequestMapping(value="/customViewResolverRequest", method=RequestMethod.GET)     
    public String customViewResolverRequestMapping() 
    {
    	System.out.println("Ritorno il nome di un component Spring che gestisce la vista");
//    	ModelAndView mav = new ModelAndView("myCustomViewResolver");
        return "myCustomViewResolver";
    }  
    
    //ViewResolver che si basa su file di properties (ResourceBundleViewResolver)
    @RequestMapping(value="/resourceBundleViewResolverRequest", method=RequestMethod.GET)     
    public String resourceBundleViewResolverRequestMapping() 
    {
    	System.out.println("resourceBundleViewResolverRequestMapping");

    	return "resourceBundleView";
    }

    //Request che carica la JSP con la form che rappresenta una Persona
    //Per preimpostare i campi della form, viene richiesto un modelAttribute "personForm"
    @RequestMapping(value="/personaFormRequest", method=RequestMethod.GET)
    public String formPersonGet(@ModelAttribute("personForm") PersonForm personForm) {
        System.out.println("formPersonGet");
//    	model.addAttribute("personForm", personForm);
        personForm.setName("Inserisci il nome");
        personForm.setSurname("Inserisci il cognome");
        System.out.println("nome e cognome: "+personForm.getName()+","+personForm.getSurname());
        return "personaFormRequest";
    }    
    
    //Request che gestisce il POST della form: riceve un oggetto del Model (una form che rappresenta una Persona)
    //Viene iniettato in BindingResult l'esito della validazione imposta nel model POJO PersonaForm
    @RequestMapping(value="/personaFormRequest", method=RequestMethod.POST)
    public String validationPersonPost(@Valid @ModelAttribute("personForm") PersonForm personForm, BindingResult result) {
        
    	if(result.hasErrors()) {
    		System.out.println("Ci sono errori e torno alla pagina chiamante");
            return "home"; //ritorno alla JSP chiamante con gli errori dentro il model
        }

        return "forward:save_person";
    }
    
    @RequestMapping(value="/save_person", method=RequestMethod.POST)
    public String savePersonPost(@ModelAttribute("personForm") PersonForm personForm) {
        
    	System.out.println("richiesta forwardata... NON ci sono errori, salvo la persona e proseguo");
        System.out.println(personForm.getName() + " " + personForm.getSurname());

        return "demo_index";
    }  
    
    
    
    //Handler che genera un'eccezione catturata dal metodo annotato con  @ExceptionHandler nel controller Advice
    @RequestMapping(value="/generateException", method=RequestMethod.GET)     
    public String generateExceptionRequestMapping() 
    {
    	throw new NullPointerException("Null pointer generato per testing");
//    	String s = null;s.charAt(1);
    	
//    	return "home";
    }    

}

